// Code_Generator.cpp

#include "../headers/Code_Generator.h"
#include "../headers/Data.h"
#include "boost/algorithm/string/predicate.hpp"
#include "boost/algorithm/string/finder.hpp"

using namespace boost::algorithm;

void Code_Generator::Process(Data<ifstream>& objInput,Data<ofstream>& objOutput)// Code_Generator process gets the data from intermediate files and uses Translate
{
	objOutput.Write("#include <iostream> \n #include <stdio.h>\n #define cpt ");// The first lines define the necessary c++ headers and memory allocation
	objOutput.WriteNumber(_ptrCount);
	objOutput.Write("\n int main(){\n");
	objOutput.Write("int* b=new int[cpt]; \n int* x= &b[");//Memory allocation
	objOutput.WriteNumber(_countLeft);
	objOutput.Write("]; \n for(int i =0 ; i<cpt-1 ;i++) {\n (*x)=0; \n x++; \n} \nfor (int i =0; i<cpt-1; i++){\n x--;\n}");
	while(!objInput.Test_EOF()) //lecture des caractere jusqu'a End Of File	
	{
		//		cout << "hello";
		_sTmp = objInput.Get_line();//renvoie ligne
		//	cout << _sTmp;
		string t = Translate(_sTmp);//methode Translate
		objOutput.Write(t);
	}
	objOutput.Write("\n delete[] b;\n return 0;\n }");// desalloue la mem
}

string Code_Generator::Translate(string t)
{
	string r;
	if (t != ""){
		int pos;
		pos=t.find(" ");// position de l'espace
		if ( boost::algorithm::istarts_with(t,"MOVE_LEFT") ){// repere si MOVE_LEFT fait partie de la chaine
					if(int(pos)==-1){// si pas d'espace (ne devrait pas arriver)
					r="\n x--;";
					}else{
					string buffer;
					buffer = t.substr(pos+1);//on ajoute la partie après l'espace qui correspond a l'entier 
					r = "\n x-= ";// l'entier est pris com la psition de lespace + 1
					r += buffer;
					r += ";";
				}
/*
 *
 *                                 Le reste  du code est similaire à la premiere partie 
 * */
		} else if ( boost::algorithm::istarts_with(t,"MOVE_RIGHT") ){
				if(int(pos)==-1){
					r="\n x++;";
				}else{
					string buffer;
					buffer = t.substr(pos+1);
					r = "\n x+= ";
					r += buffer;
					r += ";";
				}
		} else if (boost::algorithm::istarts_with(t,"ADD")) {
				if (int(pos)==-1) {
					r="\n (*x)++;";
				} else {
					string buffer;
					buffer = t.substr(pos+1);
					r = "\n (*x) += ";
					r += buffer;
						r += ";";
				}
		} else	if (boost::algorithm::istarts_with(t,"SUB")) {
				if (int(pos)==-1) {
					r="\n (*x)--;";
				} else {
					string buffer;
					buffer = t.substr(pos+1);
					r = "\n (*x) -= ";
					r += buffer;
					r += ";";
				}
		} else 	if (boost::algorithm::istarts_with(t,"START_LOOP")) {
				r="\n while(*x) {";
		} else if (boost::algorithm::istarts_with(t,"END_LOOP")) {
				r="\n }";
		} else if (boost::algorithm::istarts_with(t,"SHOW")) {
				r="\n putchar(*x);";
		} else if (boost::algorithm::istarts_with(t,"GET")) {
				r="\n (*x) = getchar();";
		} else {
				r="";
		}
				
		return r;
	} else {
		return "";
	}
}

void Code_Generator::Set_ptrCount(int foo)
{
	_ptrCount=foo;
}
void Code_Generator::Set_countLeft(int foo)
{
	_countLeft=foo;
}
